package com.cskaoyan.config;

import com.cskaoyan.shiro.CustomMarketSessionManager;
import com.cskaoyan.shiro.CustomRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;


/**
 * @author 楚夏三分
 * @datetime 2023/1/1 10:31
 * @description: TODO: Shrio权限管理相关配置 \ 组件注册
 */
@Configuration
public class ShiroConfiguration {
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 保证map中的值是有序的 使用LinkedHashMap
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // map 中的 K-V 分别是请求url和filter名称
        // 不具备认证也可以访问的匿名请求
        filterChainDefinitionMap.put("/admin/auth/login","anon");
        filterChainDefinitionMap.put("/admin/auth/info","anon");
        filterChainDefinitionMap.put("/admin/auth/401","anon");
        filterChainDefinitionMap.put("/admin/auth/logout","anon");

        // admin开头的请求需要authc-Filter进行认证
        filterChainDefinitionMap.put("/admin/**","authc");

        // 修改重定向的地址
        shiroFilterFactoryBean.setLoginUrl("/admin/auth/401");

        // 添加指定接口的所需权限, 可用此方法, 实际在对应接口上使用@RequiresPermissions注解
        // filterChainDefinitionMap.put("/admin/admin/list", "perms[admin:admin:list]");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(CustomRealm customRealm, CustomMarketSessionManager sessionManager){
        // 新建SecurityManager
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置SecurityManager的Realm域与SessionManager
        securityManager.setRealm(customRealm);

        // 如果设置多个Realm则使用此方法
        // securityManager.setRealms(Collection<customRealm> customRealms);

        // 设置Session有效时长为9999999ms
        sessionManager.setGlobalSessionTimeout(9999999);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }


    @Bean
    public DefaultWebSessionManager sessionManager(){
        return new CustomMarketSessionManager();
    }


    // 授权管理组件
    // 用到AspectJ → 使用注解的方式，将权限和url绑定起来
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}
